package org.spring.aicloud.config;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.spring.aicloud.entity.SecurityUserDetails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;


/**
 * @author yexiebao
 * @date 2025/5/11
 * 登录认证过滤器
 */
@Component
public class LoginAuthenticationFilter extends OncePerRequestFilter {
    @Value("${jwt.secret}")
    private String jwtSecret;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //1.获取jwt令牌
        String token = request.getHeader("Authorization");
        //2.判断jwt令牌是否不为空
        if (StringUtils.hasLength(token)) {
            //3.判断jwt令牌是否正确
            if(JWTUtil.verify(token,jwtSecret.getBytes())){
                //4.获取用户信息存储到Security中
                JWT jwt = JWTUtil.parseToken(token);
                if(jwt != null && jwt.getPayload("uid") != null){
                    Long uid = Long.parseLong(jwt.getPayload("uid").toString());
                    String  username = jwt.getPayload("username").toString();
                    //1.创建SecurityUserDetails对象(继承自Spring Security的UserDetails接口)
                    SecurityUserDetails securityUserDetails = new SecurityUserDetails(uid, username, "");
                    //2. 创建UsernamePasswordAuthenticationToken（Spring Security的核心认证令牌）
                    UsernamePasswordAuthenticationToken authenticationToken =
                            new UsernamePasswordAuthenticationToken(securityUserDetails,
                                    null,
                                    securityUserDetails.getAuthorities());
                    //3.将HTTP请求的详细信息（如IP、会话ID等）附加到认证令牌
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    //4.将认证令牌设置到当前安全上下文中,SecurityContextHolder是ThreadLocal的持有者，存储当前线程的安全上下文
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }

            }

        }
        filterChain.doFilter(request, response);
    }
}